/*
 * Created by Jaren at 2021/10/29 14:13
 */
import 'dart:typed_data';

import 'package:binary/binary.dart';
import 'package:inmotion_protocol/common/mode.dart';
import 'package:inmotion_protocol/common/vehicle_info.dart';
import 'package:inmotion_protocol/ezcan/bean/real_time_info.dart';
import 'package:inmotion_protocol/util/byte_util.dart';

class EBikeAllRealTimeInfo extends AbsAllRealTimeInfo {
  EBikeAllRealTimeInfo(AbsRealTimeInfo realTimeInfo, AbsRealTimeState realTimeState, AbsRealTimeError realTimeError) : super(realTimeInfo, realTimeState, realTimeError);
}

class EBikeRealTimeInfo extends AbsRealTimeInfo {
  EBikeRealTimeInfo.fromFastMsgRsp(ProductProperty property, Uint8ClampedList bytes) : super.fromBytes(property, bytes) {
    totalMileage = ByteUtil.toUint32((ByteUtil.bytes2Uint32Le(bytes, 44).value * 1.08 / 10).round());
    batteryLevel = Uint16(_parseBatteryLevel(voltage.value));
  }

  int _parseBatteryLevel(int voltage) {
    if (voltage > 4050) {
      return 10000;
    } else if (voltage > 3850) {
      return ((((voltage - 3850) / (4050 - 3850)) * 0.25 + 0.75) * 10000).round();
    } else if (voltage > 3600) {
      return ((((voltage - 3600) / (3850 - 3600)) * 0.25 + 0.5) * 10000).round();
    } else if (voltage > 3500) {
      return ((((voltage - 3500) / (3600 - 3500)) * 0.25 + 0.25) * 10000).round();
    } else if (voltage > 3400) {
      return ((((voltage - 3400) / (3500 - 3400)) * 0.25) * 10000).round();
    } else {
      return 0;
    }
  }
}

class EBikeRealTimeState extends AbsRealTimeState {
  EBikeRealTimeState.fromFastMsgRsp(Uint8ClampedList bytes) : super.fromBytes(bytes) {
    pcModeValue = ByteUtil.bytes2Uint32Le(bytes, 60);
    int tmpPcMode = pcModeValue.value & 0x0F;
    switch (tmpPcMode) {
      case 0:
        pcMode = Mode.idle;
        lockState = Uint4(0);
        break;
      case 1:
        pcMode = Mode.working;
        lockState = Uint4(0);
        break;
      case 5:
        pcMode = Mode.locked;
        lockState = Uint4(1);
        break;
    }
  }

  EBikeRealTimeState.fromSlowMsgRsp(Uint8ClampedList bytes) : super.fromBytes(bytes);
}

class EBikeRealTimeError extends AbsRealTimeError {
  Uint4 brakeHandleState = Uint4.zero; // 刹车把手故障
  Uint4 accHandleState = Uint4.zero; // 油门把手故障
  Uint4 overVoltageState = Uint4.zero; // 过压
  Uint4 lowVoltageState = Uint4.zero; // 欠压
  Uint4 controllerState = Uint4.zero; // 控制器错误
  Uint4 motorPhaseState = Uint4.zero; // 电机缺相错误
  Uint4 motorHallState = Uint4.zero; // 电机霍尔异常
  Uint4 comState = Uint4.zero; // 通讯错误

  EBikeRealTimeError.fromErrorCodeMsgRsp(Uint8ClampedList bytes) : super.fromBytes(bytes) {
    originalValue = ByteUtil.bytes2Uint32Le(bytes);
    int v = originalValue.value;
    // errors
    if ((v & 0x01) == 0x01) {
      brakeHandleState = Uint4(1);
    }
    if ((v & 0x02) == 0x02) {
      accHandleState = Uint4(1);
    }
    if ((v & 0x04) == 0x04) {
      overVoltageState = Uint4(1);
    }
    if ((v & 0x08) == 0x08) {
      lowVoltageState = Uint4(1);
    }
    if ((v & 0x10) == 0x10) {
      controllerState = Uint4(1);
    }
    if ((v & 0x20) == 0x20) {
      motorPhaseState = Uint4(1);
    }
    if ((v & 0x40) == 0x40) {
      motorHallState = Uint4(1);
    }

    if ((v & 0x8000) == 0x8000) {
      comState = Uint4(1);
    }
  }
}

class P1AllRealTimeInfo extends EBikeAllRealTimeInfo {
  P1AllRealTimeInfo(AbsRealTimeInfo realTimeInfo, AbsRealTimeState realTimeState, AbsRealTimeError realTimeError) : super(realTimeInfo, realTimeState, realTimeError);
}

class P1RealTimeInfo extends EBikeRealTimeInfo {
  P1RealTimeInfo.fromFastMsgRsp(ProductProperty property, Uint8ClampedList bytes) : super.fromFastMsgRsp(property, bytes);
}

class P1RealTimeState extends EBikeRealTimeState {
  P1RealTimeState.fromFastMsgRsp(Uint8ClampedList bytes) : super.fromFastMsgRsp(bytes);
}

class P1RealTimeError extends EBikeRealTimeError {
  P1RealTimeError.fromErrorCodeMsgRsp(Uint8ClampedList bytes) : super.fromErrorCodeMsgRsp(bytes);
}

class P2LikeAllRealTimeInfo extends EBikeAllRealTimeInfo {
  P2LikeAllRealTimeInfo(AbsRealTimeInfo realTimeInfo, AbsRealTimeState realTimeState, AbsRealTimeError realTimeError) : super(realTimeInfo, realTimeState, realTimeError);
}

class P2LikeRealTimeInfo extends EBikeRealTimeInfo {
  P2LikeRealTimeInfo.fromFastMsgRsp(ProductProperty property, Uint8ClampedList bytes) : super.fromFastMsgRsp(property, bytes);

  @override
  String toString() {
    return 'P2LikeRealTimeInfo{}';
  }
}

class P2LikeRealTimeState extends EBikeRealTimeState {
  P2LikeRealTimeState.fromFastMsgRsp(Uint8ClampedList bytes) : super.fromFastMsgRsp(bytes);
}

class P2LikeRealTimeError extends EBikeRealTimeError {
  P2LikeRealTimeError.fromErrorCodeMsgRsp(Uint8ClampedList bytes) : super.fromErrorCodeMsgRsp(bytes);
}
